package com.powernode.strategy.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.powernode.config.WxAuthConfig;
import com.powernode.constant.AuthConstants;
import com.powernode.domain.LoginMember;
import com.powernode.mapper.LoginMemberMapper;
import com.powernode.model.SecurityUser;
import com.powernode.strategy.LoginStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 商城用户购物系统登录策略具体实现
 */
@Service(AuthConstants.MEMBER_LOGIN)
@Slf4j
public class MemberLoginStrategy implements LoginStrategy {

    @Autowired
    private WxAuthConfig wxAuthConfig;

    @Autowired
    private LoginMemberMapper loginMemberMapper;

    @Override
    public UserDetails realLogin(String username) {
        log.info("====================进入会员登录策略======================");
        // 调用 登录凭证校验接口
//        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
        String realUrl = String.format(wxAuthConfig.getUrl(), wxAuthConfig.getAppid(), wxAuthConfig.getSecret(), username);
        // 发送请求
        String resultJsonStr = HttpUtil.get(realUrl);
        // 解析json格式的字符串
        JSONObject jsonObject = JSONObject.parseObject(resultJsonStr);
        // 获取微信的唯一标识openid
        String openid = jsonObject.getString("openid");
        // 判断是否有值
        if (!StringUtils.hasText(openid)) {
            throw new InternalAuthenticationServiceException("登录异常，请重试");
        }
        // 根据用户名查询用户对象
        LoginMember loginMember = loginMemberMapper.selectOne(new LambdaQueryWrapper<LoginMember>()
                .eq(LoginMember::getOpenId, openid)
        );
        // 判断用户是否存在
        if (ObjectUtil.isNull(loginMember)) {
            // 创建微信小程序内的用户体系
            // 当前用户不存在：注册一个用户（本质：就是将当前的openid存放到我们的用户体系内）
            loginMember = registerMember(openid);
        }
        // 存在：返回security框架认识的安全认证框架对象
        // 创建统一返回安全认证用户对象SecurityUser
        SecurityUser securityUser = new SecurityUser();
        securityUser.setUserId(loginMember.getId());
        securityUser.setLoginType(AuthConstants.MEMBER_LOGIN);
        securityUser.setUsername(openid);
        securityUser.setStatus(loginMember.getStatus());
        securityUser.setPassword(wxAuthConfig.getPwd());
        securityUser.setOpenid(openid);

        return securityUser;
    }

    private LoginMember registerMember(String openid) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = request.getRemoteAddr();

        LoginMember loginMember = new LoginMember();
        loginMember.setOpenId(openid);
        loginMember.setCreateTime(new Date());
        loginMember.setUpdateTime(new Date());
        loginMember.setUserLasttime(new Date());
        loginMember.setStatus(1);
        loginMember.setUserRegip(ip);
        loginMember.setUserLastip(ip);
        // 积分业务的处理
        loginMember.setScore(0);
        // 新增会员
        loginMemberMapper.insert(loginMember);
        return loginMember;
    }

    /*public static void main(String[] args) {
        // 生成微信小程序固定的密码，微信小程序的登录流程不需要密码，但是security框架是必须需要密码，所以我们给定一个固定的密码
        System.out.println(new BCryptPasswordEncoder().encode("WECHAT"));
    }*/
}
